let simulation;
const tooltip = d3.select("#tooltip");

function initGraph() {
    const svg = d3.select("#graphSection svg");
    if (!svg.attr("width")) {
        const width = window.innerWidth * 0.6;
        const height = window.innerHeight - 200;
        svg.attr("width", width).attr("height", height);
        loadData();
    }
}

function loadData() {
    const queryType = document.getElementById('queryType').value;
    const limitCount = parseInt(document.getElementById('limitCount').value);
    const url = `/api/data/${queryType}${limitCount > 0 ? `?limit=${limitCount}` : ''}`;

    fetch(url)
        .then(response => response.json())
        .then(function(data) {
            if (data.success && data.data) {
                console.log('Graph data:', data.data);
                if (queryType === 'artifact-qixing') {
                    renderQixingGraph(data.data);
                } else if (queryType === 'artifact-pattern') {
                    renderPatternGraph(data.data);
                } else {
                    renderGraph(data.data.nodes, data.data.links);
                }
            } else {
                console.error('Invalid data format:', data);
            }
        })
        .catch(error => console.error('Error fetching the data:', error));
}

let currentZoom = d3.zoomIdentity;
let isZoomMode = false; // 控制缩放模式的状态

function renderGraph(nodes, links) {
    if (!nodes || !links || nodes.length === 0) {
        console.warn('No nodes or links to render');
        return;
    }

    const svg = d3.select("#graphSection svg");
    const width = parseInt(svg.attr("width")) || window.innerWidth * 0.6;
    const height = parseInt(svg.attr("height")) || window.innerHeight - 200;
    
    svg.selectAll("*").remove();

    // 添加缩放控制器
    const zoomControls = d3.select("#graphSection")
        .append("div")
        .attr("class", "zoom-controls")
        .style("position", "absolute")
        .style("top", "0px")
        .style("right", "10px") // 调整位置到右侧
        .style("background", "white")
        .style("padding", "5px")
        .style("border-radius", "5px")
        .style("box-shadow", "0 2px 4px rgba(0,0,0,0.1)")
        .style("display", "flex")
        .style("align-items", "center");

    // 添加模式切换按钮
    const toggleButton = zoomControls.append("button")
        .attr("class", "mode-toggle")
        .style("margin", "5px")
        .style("padding", "5px 10px")
        .text("缩放模式: 关闭")
        .on("click", () => {
            isZoomMode = !isZoomMode;
            toggleButton.text(`缩放模式: ${isZoomMode ? '开启' : '关闭'}`);
            // 更新缩放和点击事件的状态
            if (isZoomMode) {
                svg.call(zoom);
                // 在缩放模式下禁用节点点击事件
                nodeGroup.selectAll('circle')
                    .on('click', null);
            } else {
                svg.on('.zoom', null);
                // 重新加载数据以重置图谱和事件
                loadData();
            }
        });

    // 添加缩放按钮
    zoomControls.append("button")
        .attr("class", "zoom-in")
        .style("margin", "5px")
        .style("padding", "5px 10px")
        .text("+")
        .on("click", () => {
            svg.transition().duration(300).call(zoom.scaleBy, 1.2);
        });

    zoomControls.append("button")
        .attr("class", "zoom-out")
        .style("margin", "5px")
        .style("padding", "5px 10px")
        .text("-")
        .on("click", () => {
            svg.transition().duration(300).call(zoom.scaleBy, 0.8);
        });

    // 添加缩放滑块
    zoomControls.append("input")
        .attr("type", "range")
        .attr("min", 10)
        .attr("max", 400)
        .attr("value", 100)
        .style("width", "100px")
        .style("margin", "0 10px")
        .on("input", function() {
            const scale = this.value / 100;
            const transform = d3.zoomIdentity.scale(scale);
            svg.transition().duration(300).call(zoom.transform, transform);
        });

    // 添加缩放功能
    const zoom = d3.zoom()
        .scaleExtent([0.1, 4])
        .filter(event => {
            // 只在缩放模式开启时启用缩放
            return isZoomMode && (event.type === "wheel" || !event.target.closest(".node"));
        })
        .on("zoom", (event) => {
            currentZoom = event.transform;
            const g = svg.selectAll(".graph-container");
            g.attr("transform", event.transform);
            // 更新滑块值
            zoomControls.select("input").property("value", event.transform.k * 100);
        })
        .on("end", () => {
            // 在缩放结束后重新绑定点击事件
            if (!isZoomMode) {
                const nodeGroup = d3.select(".nodes");
                nodeGroup.selectAll('circle')
                    .on('click', function(event, d) {
                        event.stopPropagation();
                        handleNodeClick(event, d);
                    });
            }
        });

    // 创建一个容器来包含所有图形元素
    const container = svg.append("g")
        .attr("class", "graph-container")
        .attr("transform", currentZoom);

    // 创建箭头标记
    container.append("defs").selectAll("marker")
        .data(["end"])
        .enter().append("marker")
        .attr("id", String)
        .attr("viewBox", "0 -5 10 10")
        .attr("refX", 20)
        .attr("refY", 0)
        .attr("markerWidth", 6)
        .attr("markerHeight", 6)
        .attr("orient", "auto")
        .append("path")
        .attr("d", "M0,-5L10,0L0,5")
        .attr("fill", "#999");

    // 创建力导向图模拟器
    simulation = d3.forceSimulation(nodes)
        .force("link", d3.forceLink(links).id(d => d.id || d.element_id).distance(d => {
            // 根据节点类型调整连接线长度
            const sourceType = d.source.type || (d.source.labels && d.source.labels[0]);
            const targetType = d.target.type || (d.target.labels && d.target.labels[0]);
            if (sourceType === 'artifact' && targetType === 'pattern') {
                return 100; // 文物与纹样之间的距离较小
            } else if (sourceType === 'artifact' && targetType === 'artifact') {
                return 250; // 文物之间的距离较大
            } else if (sourceType === 'CulturalItem' && targetType === 'CulturalItem') {
                return 250; // 增加文物之间的距离
            } else if (sourceType === 'CulturalItem' || targetType === 'CulturalItem') {
                return 180; // 文物与其他节点的距离适中
            }
            return 150; // 其他关系的距离
        }))
        .force("charge", d3.forceManyBody().strength(d => {
            // 根据节点类型调整斥力
            if (d.type === 'artifact') {
                return -800; // 文物节点斥力较大
            } else if (d.type === 'pattern') {
                return -200; // 纹样节点斥力较小
            }
            return d.labels && d.labels.includes('CulturalItem') ? -800 : -400;
        }))
        .force("center", d3.forceCenter(width / 2, height / 2))
        .force("collide", d3.forceCollide().radius(d => {
            // 根据节点类型调整碰撞半径
            if (d.type === 'artifact') {
                return 60; // 文物节点碰撞半径较大
            } else if (d.type === 'pattern') {
                return 30; // 纹样节点碰撞半径较小
            }
            return d.labels && d.labels.includes('CulturalItem') ? 80 : 50;
        }));

    // 添加径向力，使文物节点更靠近中心
    simulation.force("radial", d3.forceRadial(
        d => d.labels.includes('CulturalItem') ? 100 : 200, // 文物节点更靠近中心
        width / 2,
        height / 2
    ).strength(0.3));

    // 添加额外的力以防止节点重叠
    simulation.force("x", d3.forceX(width / 2).strength(0.05))
             .force("y", d3.forceY(height / 2).strength(0.05));

    // 创建连接线
    const link = container.append("g")
        .attr("class", "links")
        .selectAll("line")
        .data(links)
        .enter().append("line")
        .attr("class", "link")
        .attr("marker-end", "url(#end)");

    // 创建节点组
    const nodeGroup = container.append("g")
        .attr("class", "nodes")
        .selectAll("g")
        .data(nodes)
        .enter().append("g")
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));

    // 添加节点圆圈
    nodeGroup.append("circle")
        .attr("class", d => `node ${d.labels[0].toLowerCase()}`)
        .attr("r", 12)
        .on("mouseover", handleNodeMouseOver)
        .on("mouseout", handleNodeMouseOut)
        .on("click", function(event, d) {
            if (!isZoomMode) {
                event.stopPropagation();
                handleNodeClick(event, d);
            }
        });

    // 确保在缩放和拖拽后重新绑定点击事件
    function rebindClickEvents() {
        if (!isZoomMode) {
            nodeGroup.selectAll('circle')
                .on('click', function(event, d) {
                    event.stopPropagation();
                    handleNodeClick(event, d);
                });
        }
    }

    // 在拖拽结束和缩放结束后重新绑定点击事件
    zoom.on("end", rebindClickEvents);
    simulation.on("end", rebindClickEvents);

    // 添加节点标签
    nodeGroup.append("text")
        .attr("class", "node-label")
        .attr("dy", ".35em")
        .attr("x", 15)
        .text(d => d.properties.name || d.properties.mean || "")
        .style("fill", "#333")
        .style("font-size", "12px");

    // 更新力导向图
    simulation.on("tick", () => {
        link
            .attr("x1", d => d.source.x)
            .attr("y1", d => d.source.y)
            .attr("x2", d => d.target.x)
            .attr("y2", d => d.target.y);

        nodeGroup
            .attr("transform", d => `translate(${d.x},${d.y})`);
    });
}

function handleNodeMouseOver(event, d) {
    const content = d.properties.name || d.properties.mean;
    const description = d.properties.description || d.properties.story || "";

    tooltip
        .style("display", "block")
        .html(`<div class="tooltip-content"><strong>${content}</strong><br/>${description}</div>`)
        .style("left", (event.pageX + 10) + "px")
        .style("top", (event.pageY - 28) + "px");

    d3.select(event.currentTarget)
        .transition()
        .duration(200)
        .attr("r", 15);
}

function handleNodeMouseOut(event) {
    tooltip.style("display", "none");
    d3.select(event.currentTarget)
        .transition()
        .duration(200)
        .attr("r", 12);
}

function handleNodeClick(event, d) {
    displayDetails(d);
}

function displayDetails(node) {
    const detailsContent = document.getElementById('detailsContent');
    
    let title = '';
    if (node.labels.includes('CulturalItem')) {
        title = node.properties.name || '未命名文物';
    } else if (node.labels.includes('Story')) {
        title = '相关故事';
    } else if (node.labels.includes('Meaning')) {
        title = '文物含义';
    }
    
    let content = '';
    if (node.labels.includes('Story')) {
        content = node.properties.story || '暂无故事内容';
    } else if (node.labels.includes('Meaning')) {
        content = node.properties.mean || '暂无含义描述';
    } else {
        content = node.properties.description || '暂无描述';
    }
    
    detailsContent.innerHTML = `
        <div class="p-4 bg-white rounded-lg shadow">
            <h3 class="text-xl font-bold mb-2">${title}</h3>
            <p class="text-gray-700">${content}</p>
        </div>
    `;
}

function dragstarted(event) {
    if (!event.active) simulation.alphaTarget(0.3).restart();
    const transform = currentZoom;
    event.subject.fx = transform.invertX(event.x);
    event.subject.fy = transform.invertY(event.y);
    // 在拖拽开始时暂时禁用点击事件，避免干扰
    if (!isZoomMode) {
        d3.select(event.sourceEvent.target)
            .on('click', null);
    }
}

function dragged(event) {
    const transform = currentZoom;
    event.subject.fx = transform.invertX(event.x);
    event.subject.fy = transform.invertY(event.y);
}

function dragended(event) {
    if (!event.active) simulation.alphaTarget(0);
    event.subject.fx = null;
    event.subject.fy = null;
    // 在拖拽结束后重新绑定点击事件
    if (!isZoomMode) {
        const nodeGroup = d3.select(".nodes");
        nodeGroup.selectAll('circle')
            .on('click', function(event, d) {
                event.stopPropagation();
                handleNodeClick(event, d);
            });
    }
}

function renderQixingGraph(data) {
    const svg = d3.select("#graphSection svg");
    const width = parseInt(svg.attr("width")) || window.innerWidth * 0.6;
    const height = parseInt(svg.attr("height")) || window.innerHeight - 200;
    
    svg.selectAll("*").remove();

    // 创建容器
    const container = svg.append("g")
        .attr("class", "graph-container");

    // 数据预处理
    const qixingGroups = new Map();
    const processedNodes = [];
    const processedLinks = [];
    const nodeMap = new Map();

    // 首先处理器型节点
    data.nodes.forEach(node => {
        if (node.type === 'qixing') {
            const safeNode = {
                id: node.id,
                name: node.name,
                type: 'qixing',
                artifacts: []
            };
            nodeMap.set(node.id, safeNode);
            qixingGroups.set(node.id, safeNode);
            processedNodes.push(safeNode);
        }
    });

    // 处理文物节点和关系
    data.nodes.forEach(node => {
        if (node.type === 'artifact') {
            const safeNode = {
                id: node.id,
                name: node.name,
                type: 'artifact'
            };
            nodeMap.set(node.id, safeNode);
            processedNodes.push(safeNode);
        }
    });

    // 处理连接
    data.links.forEach(link => {
        const source = nodeMap.get(link.source);
        const target = nodeMap.get(link.target);
        if (source && target) {
            processedLinks.push({
                source: source.id,
                target: target.id
            });
            // 将文物添加到对应的器型组
            if (target.type === 'qixing') {
                target.artifacts.push(source);
            }
        }
    });

    // 创建力导向图
    simulation = d3.forceSimulation(processedNodes)
        .force("link", d3.forceLink(processedLinks)
            .id(d => d.id)
            .distance(d => 100))
        .force("charge", d3.forceManyBody()
            .strength(d => d.type === 'qixing' ? -1000 : -200))
        .force("center", d3.forceCenter(width / 2, height / 2))
        .force("collide", d3.forceCollide()
            .radius(d => d.type === 'qixing' ? 60 : 20))
        .force("radial", d3.forceRadial(
            d => d.type === 'qixing' ? 0 : 200,
            width / 2,
            height / 2
        ).strength(0.8));

    // 创建连接线
    const link = container.append("g")
        .attr("class", "links")
        .selectAll("line")
        .data(processedLinks)
        .enter().append("line")
        .attr("class", "link")
        .style("stroke", "#999")
        .style("stroke-width", 1);

    // 创建节点组
    const nodeGroup = container.append("g")
        .attr("class", "nodes")
        .selectAll("g")
        .data(processedNodes)
        .enter().append("g")
        .attr("class", "node-group")
        .call(d3.drag()
            .on("start", dragstarted)
            .on("drag", dragged)
            .on("end", dragended));

    // 添加节点
    nodeGroup.append("circle")
        .attr("class", d => `node ${d.type}`)
        .attr("r", d => d.type === 'qixing' ? 30 : 8)
        .style("fill", d => d.type === 'qixing' ? '#ff7f0e' : '#ff5733')
        .style("stroke", d => d.type === 'qixing' ? '#d66b0d' : '#fff')
        .style("stroke-width", d => d.type === 'qixing' ? 3 : 1.5);

    // 添加文本标签
    nodeGroup.append("text")
        .attr("class", "node-label")
        .attr("dy", d => d.type === 'qixing' ? -35 : 15)
        .text(d => d.name)
        .attr("text-anchor", "middle")
        .style("font-size", d => d.type === 'qixing' ? '14px' : '12px')
        .style("font-weight", d => d.type === 'qixing' ? 'bold' : 'normal');

    // 添加交互事件
    nodeGroup
        .on("mouseover", function(event, d) {
            const content = d.type === 'qixing' 
                ? `<strong>${d.name}</strong><br>相关文物数量: ${d.artifacts.length}`
                : `<strong>${d.name}</strong>`;

            tooltip.html(content)
                .style("left", (event.pageX + 10) + "px")
                .style("top", (event.pageY - 10) + "px")
                .style("display", "block");

            // 高亮相关节点和连接
            const relatedNodes = new Set();
            if (d.type === 'qixing') {
                d.artifacts.forEach(artifact => relatedNodes.add(artifact.id));
            } else {
                processedLinks.forEach(l => {
                    if (l.source.id === d.id || l.source === d.id) relatedNodes.add(l.target);
                    if (l.target.id === d.id || l.target === d.id) relatedNodes.add(l.source);
                });
            }

            nodeGroup.style("opacity", n => relatedNodes.has(n.id) || n.id === d.id ? 1 : 0.1);
            link.style("opacity", l => 
                (l.source.id === d.id || l.source === d.id || 
                 l.target.id === d.id || l.target === d.id) ? 1 : 0.1
            );
        })
        .on("mouseout", function() {
            tooltip.style("display", "none");
            nodeGroup.style("opacity", 1);
            link.style("opacity", 0.6);
        })
        .on("click", function(event, d) {
            displayQixingDetails(d);
        });

    // 更新力导向图
    simulation.on("tick", () => {
        link
            .attr("x1", d => d.source.x)
            .attr("y1", d => d.source.y)
            .attr("x2", d => d.target.x)
            .attr("y2", d => d.target.y);

        nodeGroup
            .attr("transform", d => `translate(${d.x},${d.y})`);
    });
}

function displayQixingDetails(node) {
    const detailsContent = document.getElementById('detailsContent');
    let content = '';
    
    if (node.type === 'qixing') {
        content = `
            <div class="p-4 bg-white rounded-lg shadow">
                <h3 class="text-xl font-bold mb-3">${node.name}</h3>
                <p class="text-gray-600 mb-2">相关文物数量：${node.artifacts.length}</p>
                <div class="mt-3">
                    <h4 class="font-semibold mb-2">相关文物列表：</h4>
                    <ul class="list-disc pl-5">
                        ${node.artifacts.map(artifact => `
                            <li class="text-gray-700">${artifact.name}</li>
                        `).join('')}
                    </ul>
                </div>
            </div>
        `;
    } else {
        content = `
            <div class="p-4 bg-white rounded-lg shadow">
                <h3 class="text-xl font-bold mb-2">${node.name}</h3>
                <p class="text-gray-700">类型：文物</p>
            </div>
        `;
    }
    
    detailsContent.innerHTML = content;
}

// 页面加载完成后初始化图谱
document.addEventListener('DOMContentLoaded', initGraph);